<?php

/**
 * Contains the basis classes for managing any objects derived from SmartObjects
 *
 * @license GNU
 * @author marcan <marcan@smartfactory.ca>
 * @version $Id: smartobjectcontroller.php,v 1.4 2007/08/23 21:17:46 marcan Exp $
 * @link http://smartfactory.ca The SmartFactory
 * @package SmartObject
 * @subpackage SmartObjectCore
 */

if (!defined("XOOPS_ROOT_PATH")) {
	die("XOOPS root path not defined");
}


/**
 * Persistable SmartObject Controller class.
 *
 * This class is responsible for providing operations to an object
 * for managing the object's manipulation
 *
 * @package SmartObject
 * @author marcan <marcan@smartfactory.ca>
 * @credit Jan Keller Pedersen <mithrandir@xoops.org> - IDG Danmark A/S <www.idg.dk>
 * @link http://smartfactory.ca The SmartFactory
 */
include_once XOOPS_ROOT_PATH."/modules/smartobject/class/smartobject.php";
include_once XOOPS_ROOT_PATH."/modules/smartobject/class/smartobjecthandler.php";

class SmartObjectController {
    var $handler;
    function SmartObjectController($handler) {
        $this->handler=$handler;
    }

    function postDataToObject(&$smartObj) {
    	foreach(array_keys($smartObj->vars) as $key) {
    		// check if this field's value is available in the POST array
    		// However, we don't need this value if it's the key field as the object has already been created
    		if (isset($_POST[$key]) && ($key != $this->handler->keyName)) {
    			// check to see of it's a value sent by a xoopsformdatetime
    			if (is_array($_POST[$key]) && isset($_POST[$key]['date']))  {
    				$value = strtotime($_POST[$key]['date']) + $_POST[$key]['time'];
    			} else {
    				$value = $_POST[$key];
    			}
    			$smartObj->setVar($key, $value);
    		}
    	}
    }

    function &doStoreFromDefaultForm(&$smartObj, $objectid, $created_success_msg, $modified_success_msg, $redirect_page=false, $debug=false)
    {
    	global $smart_previous_page;

		$this->postDataToObject($smartObj);

    	if ($smartObj->isNew()) {
			$redirect_msg = $created_success_msg;
		} else {
			$redirect_msg = $modified_success_msg;
		}

		// Check if there were uploaded images

		/**
		 * @TODO This is a problem as it only takes care of images. We need to also manage files
		 * tahat would be uploaded via the "file" control
		 */

		if (isset($_POST['smart_upload_image'])) {
		    include_once XOOPS_ROOT_PATH."/modules/smartobject/class/smartuploader.php";
			$uploaderObj = new SmartUploader($smartObj->getImageDir(true), $this->handler->_allowedMimeTypes, $this->handler->_maxFileSize, $this->handler->_maxWidth, $this->handler->_maxHeight);
			foreach ($_FILES as $name=>$file_array) {
				if (isset ($file_array['name']) && $file_array['name'] != "" ) {
					if ($uploaderObj->fetchMedia($name)) {
						$uploaderObj->setTargetFileName(time()."_". $uploaderObj->getMediaName());
						if ($uploaderObj->upload()) {
							// Find the related field in the SmartObject
							$related_field = str_replace('upload_', '', $name);
							$smartObj->setVar($related_field, $uploaderObj->getSavedFileName());
						} else {
							$smartObj->setErrors($uploaderObj->getErrors(false));
						}
					} else {
						$smartObj->setErrors($uploaderObj->getErrors(false));
					}
				}
			}
		}

		if ($debug) {
			$storeResult = $this->handler->insertD($smartObj);
		} else {
			$storeResult = $this->handler->insert($smartObj);
		}

		if ($storeResult) {
			if ($this->handler->getPermissions()) {
				$smartpermissions_handler = new SmartobjectPermissionHandler($this->handler);
				$smartpermissions_handler->storeAllPermissionsForId($smartObj->id());
			}
		}

		if ($redirect_page === null) {
			return $smartObj;
		} else {
			if ( !$storeResult ) {
				redirect_header($smart_previous_page, 3, _CO_OBJ_SAVE_ERROR . $smartObj->getHtmlErrors());
			}

			$redirect_page = $redirect_page ? $redirect_page : smart_get_page_before_form();

			redirect_header($redirect_page, 2, $redirect_msg);
		}
    }

    /**
     * Store the object in the database autmatically from a form sending POST data
     *
     * @param string $created_success_msg message to display if new object was created
     * @param string $modified_success_msg message to display if object was successfully edited
     * @param string $created_redir_page redirect page after creating the object
     * @param string $modified_redir_page redirect page after editing the object
     * @param string $redirect_page redirect page, if not set, then we backup once
     * @param bool $exit if set to TRUE then the script ends
     * @return bool
     */
    function &storeFromDefaultForm($created_success_msg, $modified_success_msg, $redirect_page=false, $debug=false)
    {
    	$objectid = (isset($_POST[$this->handler->keyName])) ? intval($_POST[$this->handler->keyName]) : 0;
    	if ($debug) {
    		$smartObj = $this->handler->getD($objectid);
    	} else {
    		$smartObj = $this->handler->get($objectid);
    	}


		// if handler is the Multilanguage handler, we will need to treat this for multilanguage
		if (is_subclass_of($this->handler, 'smartpersistablemlobjecthandler')) {

			if ($smartObj->isNew()) {
				// This is a new object. We need to store the meta data and then the language data
				// First, we will get rid of the multilanguage data to only store the meta data
				$smartObj->stripMultilanguageFields();
				$newObject =& $this->doStoreFromDefaultForm($smartObj, $objectid, $created_success_msg, $modified_success_msg, $redirect_page, $debug);
				/**
				 * @todo we need to trap potential errors here
				 */

				// ok, the meta daa is stored. Let's recreate the object and then
				// get rid of anything not multilanguage
				unset($smartObj);
				$smartObj = $this->handler->get($objectid);
				$smartObj->stripNonMultilanguageFields();

				$smartObj->setVar($this->handler->keyName, $newObject->getVar($this->handler->keyName));
				$this->handler->changeTableNameForML();
				$ret =& $this->doStoreFromDefaultForm($smartObj, $objectid, $created_success_msg, $modified_success_msg, $redirect_page, $debug);

				return $ret;
			}
		} else {
			return $this->doStoreFromDefaultForm($smartObj, $objectid, $created_success_msg, $modified_success_msg, $redirect_page, $debug);
		}
    }

    function &storeSmartObjectD() {
    	return $this->storeSmartObject(true);
    }

    function &storeSmartObject($debug=false)
    {
    	$ret =& $this->storeFromDefaultForm('', '', null, $debug);

    	return $ret;
    }

    /**
     * Handles deletion of an object which keyid is passed as a GET param
     *
     * @param string $redir_page redirect page after deleting the object
     * @return bool
     */
    function handleObjectDeletion($confirm_msg = false, $op='del')
    {
		global $smart_previous_page;

    	$objectid = (isset($_REQUEST[$this->handler->keyName])) ? intval($_REQUEST[$this->handler->keyName]) : 0;
    	$smartObj = $this->handler->get($objectid);

		if ($smartObj->isNew()) {
			redirect_header("javascript:history.go(-1)", 3, _CO_SOBJECT_NOT_SELECTED);
			exit();
		}

		$confirm = (isset($_POST['confirm'])) ? $_POST['confirm'] : 0;
		if ($confirm) {
			if( !$this->handler->delete($smartObj)) {
				redirect_header($_POST['redirect_page'], 3, _CO_SOBJECT_DELETE_ERROR . $smartObj->getHtmlErrors());
				exit;
			}

			redirect_header($_POST['redirect_page'], 3, _CO_SOBJECT_DELETE_SUCCESS);
			exit();
		} else {
			// no confirm: show deletion condition

				xoops_cp_header();

			if (!$confirm_msg) {
				$confirm_msg = _CO_SOBJECT_DELETE_CONFIRM;
			}

			xoops_confirm(array('op' => $op, $this->handler->keyName => $smartObj->getVar($this->handler->keyName), 'confirm' => 1, 'redirect_page' => $smart_previous_page), xoops_getenv('PHP_SELF'), sprintf($confirm_msg , $smartObj->getVar($this->handler->identifierName)), _CO_SOBJECT_DELETE);

				xoops_cp_footer();

		}
		exit();
    }

    /**
     * Retreive the object admin side link for a {@link SmartObjectSingleView} page
     *
     * @param object $smartObj reference to the object from which we want the user side link
     * @param bool $onlyUrl wether or not to return a simple URL or a full <a> link
     * @return string admin side link to the object
     */
    function getAdminViewItemLink($smartObj, $onlyUrl=false, $withimage=false)
    {
    	$ret = $this->handler->_moduleUrl . "admin/" . $this->handler->_page . "?op=view&" . $this->handler->keyName . "=" . $smartObj->getVar($this->handler->keyName);
		if ($onlyUrl) {
			return $ret;
		}
		elseif($withimage) {
			return "<a href='" . $ret . "'><img src='" . SMARTOBJECT_IMAGES_ACTIONS_URL . "viewmag.png' style='vertical-align: middle;' alt='" . _CO_SOBJECT_ADMIN_VIEW . "'  title='" . _CO_SOBJECT_ADMIN_VIEW . "'/></a>";
		}

    	return "<a href='" . $ret . "'>" . $smartObj->getVar($this->handler->identifierName) . "</a>";
    }

    /**
     * Retreive the object user side link
     *
     * @param object $smartObj reference to the object from which we want the user side link
     * @param bool $onlyUrl wether or not to return a simple URL or a full <a> link
     * @return string user side link to the object
     */
    function getItemLink(&$smartObj, $onlyUrl=false)
    {
        $seoMode = smart_getModuleModeSEO($this->handler->_moduleName);
        $seoModuleName = smart_getModuleNameForSEO($this->handler->_moduleName);

        /**
         * $seoIncludeId feature is not finished yet, so let's put it always to true
         */
        //$seoIncludeId = smart_getModuleIncludeIdSEO($this->handler->_moduleName);
		$seoIncludeId = true;

        if ($seoMode == 'rewrite') {
	    	$ret = XOOPS_URL . '/' . $seoModuleName .
				'.' . $this->handler->_itemname .
				($seoIncludeId ? '.'	. $smartObj->getVar($this->handler->keyName) : ''). '/' . $smartObj->getVar('short_url') . '.html';
        } else if ($seoMode == 'pathinfo') {
	    	$ret = SMARTOBJECT_URL . 'seo.php/' . $seoModuleName .
				'.' . $this->handler->_itemname .
				($seoIncludeId ? '.'	. $smartObj->getVar($this->handler->keyName) : ''). '/' . $smartObj->getVar('short_url') . '.html';
        } else {
    		$ret = $this->handler->_moduleUrl . $this->handler->_page . "?" . $this->handler->keyName . "=" . $smartObj->getVar($this->handler->keyName);
        }

		if (!$onlyUrl) {
			$ret = "<a href='" . $ret . "'>" . $smartObj->getVar($this->handler->identifierName) . "</a>";
		}
    	return $ret;
    }

    function getEditLanguageLink($smartObj, $onlyUrl=false, $withimage=true)
    {
    	$ret = $this->handler->_moduleUrl . "admin/" . $this->handler->_page . "?op=mod&" . $this->handler->keyName . "=" . $smartObj->getVar($this->handler->keyName) . "&language=" . $smartObj->getVar('language');
		if ($onlyUrl) {
			return $ret;
		}
		elseif($withimage) {
			return "<a href='" . $ret . "'><img src='" . SMARTOBJECT_IMAGES_ACTIONS_URL . "wizard.png' style='vertical-align: middle;' alt='" . _CO_SOBJECT_LANGUAGE_MODIFY . "'  title='" . _CO_SOBJECT_LANGUAGE_MODIFY . "'/></a>";
		}

    	return "<a href='" . $ret . "'>" . $smartObj->getVar($this->handler->identifierName) . "</a>";
    }

    function getEditItemLink($smartObj, $onlyUrl=false, $withimage=true)
    {
    	$ret = $this->handler->_moduleUrl . "admin/" . $this->handler->_page . "?op=mod&" . $this->handler->keyName . "=" . $smartObj->getVar($this->handler->keyName);
		if ($onlyUrl) {
			return $ret;
		}
		elseif($withimage) {
			return "<a href='" . $ret . "'><img src='" . SMARTOBJECT_IMAGES_ACTIONS_URL . "edit.png' style='vertical-align: middle;' alt='" . _CO_SOBJECT_MODIFY . "'  title='" . _CO_SOBJECT_MODIFY . "'/></a>";
		}

    	return "<a href='" . $ret . "'>" . $smartObj->getVar($this->handler->identifierName) . "</a>";
    }

    function getDeleteItemLink($smartObj, $onlyUrl=false, $withimage=true)
    {
    	$ret = $this->handler->_moduleUrl . "admin/" . $this->handler->_page . "?op=del&" . $this->handler->keyName . "=" . $smartObj->getVar($this->handler->keyName);
		if ($onlyUrl) {
			return $ret;
		}
		elseif($withimage) {
			return "<a href='" . $ret . "'><img src='" . SMARTOBJECT_IMAGES_ACTIONS_URL . "editdelete.png' style='vertical-align: middle;' alt='" . _CO_SOBJECT_DELETE . "'  title='" . _CO_SOBJECT_DELETE . "'/></a>";
		}

    	return "<a href='" . $ret . "'>" . $smartObj->getVar($this->handler->identifierName) . "</a>";
    }

    function getPrintAndMailLink($smartObj) {
    	global $xoopsConfig;

    	$printlink = $this->handler->_moduleUrl . "print.php?" . $this->handler->keyName . "=" . $smartObj->getVar($this->handler->keyName);
		$js = "javascript:openWithSelfMain('" . $printlink . "', 'smartpopup', 700, 519);";
		$printlink = '<a href="' . $js . '"><img  src="' . SMARTOBJECT_IMAGES_ACTIONS_URL . 'fileprint.png" alt="" style="vertical-align: middle;"/></a>';

		$smartModule = smart_getModuleInfo($smartObj->handler->_moduleName);
		$link = smart_getCurrentPage();
		$mid = $smartModule->getVar('mid');
		$friendlink = "<a href=\"javascript:openWithSelfMain('".SMARTOBJECT_URL."sendlink.php?link=" . $link . "&amp;mid=" . $mid . "', 'sendmessage', 674, 500);\"><img src=\"".SMARTOBJECT_IMAGES_ACTIONS_URL . "mail_send.png\"  alt=\"" . _CO_SOBJECT_EMAIL . "\" title=\"" . _CO_SOBJECT_EMAIL . "\" style=\"vertical-align: middle;\"/></a>";

		$ret = '<span id="smartobject_print_button">' . $printlink . "&nbsp;</span>" . '<span id="smartobject_mail_button">' . $friendlink . '</span>';
		return $ret;
    }

    function getModuleItemString() {
    	$ret = $this->handler->_moduleName . '_' . $this->handler->_itemname;
    	return $ret;
    }
}